package org.dawing.shop.cart.command.aggregate;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.model.AggregateIdentifier;
import org.axonframework.commandhandling.model.AggregateMember;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.spring.stereotype.Aggregate;
import org.dawning.shop.common.commands.cart.AddToCartCommand;
import org.dawning.shop.common.commands.cart.ChangeProductQuantityCommand;
import org.dawning.shop.common.commands.cart.CreateCartCommand;
import org.dawning.shop.common.domain.cart.CartId;
import org.dawning.shop.common.domain.cart.CartProduct;
import org.dawning.shop.common.events.cart.CartAddEvent;
import org.dawning.shop.common.events.cart.CartCreateEvent;
import org.dawning.shop.common.events.cart.ProductQuantityChangeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;

/**
 * Created by miou on 2017/6/13 0013.
 */
@Aggregate
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CartAggregate {

    private Logger logger = LoggerFactory.getLogger(CartAggregate.class);

    @AggregateIdentifier
    private CartId id;

    @AggregateMember
    private Map<String,CartProduct> cartProduct;

    private BigDecimal totalPrice;

    private long totalQuantity;

    @CommandHandler
    public void CartAggregate(CreateCartCommand command) throws Exception {
        logger.info("apply create product command : " + command.toString());
        apply(new CartCreateEvent(command.getCartId(), command.getCartProduct(),command.getSku()));
    }

    @CommandHandler
    public void on(AddToCartCommand command){
        apply(new CartAddEvent(command.getCartId(), command.getCartProduct(),command.getSku()));
    }

    @CommandHandler
    public void on(ChangeProductQuantityCommand command){
        apply(new ProductQuantityChangeEvent(command.getCartId(),command.getShopId(),command.getSku(),command.getQuantity()));
    }

    @EventHandler
    public void on(CartCreateEvent event){
        this.id = event.getCartId();
        this.cartProduct = new HashMap<>();
        cartProduct.put(event.getCartProduct().getShopId()+event.getSku(),event.getCartProduct());
    }

    @EventHandler
    public void on(CartAddEvent event){
        this.cartProduct.put(event.getCartProduct().getShopId()+event.getSku(),event.getCartProduct());

    }

    @EventHandler
    public void on(ProductQuantityChangeEvent event){
        CartProduct vo = this.cartProduct.get(event.getShopId()+event.getSku());
        vo.setQuantity(event.getQuantity());
        this.cartProduct.put(event.getShopId()+event.getSku(),vo);
    }
}
